#include "defs.h"
#include "matriz.h"
#include "sistemas.h"

int n;

int main(int argc, char** argv)
{
	bool pelea = false;
	
	if (argc == 5)
	{
		/* Otros tiros. */
		pelea = true;		
	}
	else if (argc != 3)
	{
		/* Error. */		
		cout << "No. " << endl;		
	}
		
	int a;
	double aux;
	int turno = 0;
	
	/* Archivos. */
	string 	 pos (argv[1]);
	ifstream posicion(pos.c_str());
	string 	 out (argv[2]);
	ofstream salida(out.c_str());
	
	/* Leer posición. */
	posicion >> a >> n;	
	
	/* Variables. */
	Matriz matriz (n, Vector(n));
	Vector disparo (n);	
	Vector x (n);
	
	/* Matríz de Hilbert. */
	Matriz hil (n, Vector(n));
	Hilbert(hil, n);
	
	forn(i, n)
	{		
		posicion >> aux;
		x[i] = aux;
	}
		
	if (pelea)
	{		
		/* Más archivos. */
		string 	 ult (argv[3]);
		ifstream ultimo(ult.c_str());
	
		/* Último: d y matríz. */
		Vector d (n);
		Matriz M (n, vdouble(n));
		
		ultimo >> turno >> a;
		
		if (a != n)
		{
			cout << "Error! No es la misma dimensión" << endl;
			exit(1);
		}
		
		/* Leer d. */
		forn(i, n)
		{		
			ultimo >> aux;
			d[i] = aux;
		}
		
		/* Leer matríz. */
		forn(i, n)
		{
			forn(j, n)
			{
				ultimo >> aux;
				M[i][j] = aux;
			}
		}
		Vector disparo1(n);		
		solvePLUPivEsc(M, d, disparo1, n);
	
		//~ Vector disparo2(n);		
		//~ solvePLU(M, d, disparo2, n);
		//~ 
		Vector disparo3(n);
		solveQR(M, d, disparo3, n);		
		
		/*Promedio el mejor disparo*/
		forn(i, n)
		{
			disparo[i] = disparo1[i] + disparo3[i];
			disparo[i] /= 2;	
		}		
		
		buscarMatriz(matriz, hil, disparo, x, n);		
		
		ultimo.close();		
	}
	else
	{
		matrizInicial(matriz, hil, disparo, x, n);
	}
	
	/* Salida */
	matrizPorVector(matriz, x, disparo, n);
	
	salida.precision(20);
	salida.setf(std::ios_base::scientific, std::ios_base::floatfield);
	
	salida << turno+1 << endl;
	salida << n << endl;
	
	/* Vector d */
	forn(i, n)		
		salida << disparo[i] << " ";
	salida << endl;
	
	/* Matríz usada */
	forn(i, n)
	{
		forn(j, n)
			salida << matriz[i][j] << " ";
			
		salida << endl;
	}
		
	posicion.close();
	salida.close();
	
	return 0;
}
